﻿using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet;
using System;
using System.Threading.Tasks;
using Zhaoxi.Communication;
using MQTTnet.Client.Connecting;
using System.Collections.Generic;

namespace Zhaoxi.Upper
{
    class Program
    {
        // 方式:
        // 1.从西门子200Smart读取数据，并通过上位机使用MQTT协议发送到MQTT服务器(本例是这种方式)。
        // 2.从西门子200Smart读取数据，并通过上位机使用HTTP协议发送到HTTP服务器。
        // 3.从西门子200Smart读取数据，并通过上位机使用WebSocket协议发送到WebSocket服务器。
        // 4.从西门子200Smart读取数据，并通过上位机使用TCP协议发送到TCP服务器。
        // 5.从西门子200Smart读取数据，并通过dtu协议转换发送给服务器。
        static async Task Main(string[] args)
        {

            await ConnectMQTT();
            // 与200Smart进行通信(用的是IoTClient工具模拟西门子200Smart)
            s7Comm = new S7Comm("127.0.0.1");
            s7Comm.Connect(0, 1);
            // 读取
            await Task.Run(async () =>
            {
                while (true)
                {
                    await Task.Delay(2000);
                    Result<ushort> result = s7Comm.Read<ushort>("VW0", 3);
                    if (!result.Status)
                        Console.WriteLine(result.Message);
                    else
                    {
                        if (state) // MqttClient连接状态为true，发布消息。
                        {
                            // 发布主题为"d/simens/value"的消息，消息内容为读取到的数据。
                            await client.PublishAsync("d/simens/value", string.Join(" ", result.Datas));
                        }
                        Console.WriteLine(string.Join(" ", result.Datas));
                    }
                }
            });

            Console.ReadLine();
        }

        static bool state = false;
        static IManagedMqttClient client = null;
        static S7Comm s7Comm;
        static async Task ConnectMQTT()
        {
            // 连接到MQTT服务器
            client = new MqttFactory().CreateManagedMqttClient();
            // 连接成功
            client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(e =>
            {
                state = true;

                // 连接完成时订阅
                client.SubscribeAsync("d/simens/VW2");
            });
            // 连接断开事件
            //client.DisconnectedHandler
            // 接收到消息
            client.ApplicationMessageReceivedHandler =
                new MqttApplicationMessageReceivedHandlerDelegate(e =>
                {
                    Console.WriteLine(e.ApplicationMessage.ConvertPayloadToString());
                    List<DataParameter> param = new List<DataParameter>
                    {
                        new DataParameter{
                            Area = Areas.DataBlock,
                            DBNumber=1,
                            ByteAddress=2,
                            BitAddress=0,
                            Count=1,
                            PValueSize=PValueSize.WORD,
                            DataType=typeof(ushort),
                            Datas=new List<object>{ ushort.Parse(e.ApplicationMessage.ConvertPayloadToString()) }
                        }
                    };

                    // 这个s7库有问题，写进去的值并不是123,可能是字节序的问题，这里就忽略这个问题了。
                    Result result = s7Comm.Write(param);

                    // 写入失败则打印错误原因
                    if (!result.Status)
                        Console.WriteLine(result.Message);

                    // 这个参数的错误信息
                    Console.WriteLine(param[0].Error);

                });

            // IP   Port   Client ID
            // UserName  Password
            IMqttClientOptions clientOptions = new MqttClientOptionsBuilder()
                .WithClientId(Guid.NewGuid().ToString())
                .WithTcpServer("127.0.0.1", 1883)// MQTT的服务器地址
                .WithCredentials("admin", "123456")
                .Build();
            IManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
                .WithClientOptions(clientOptions)
                .Build();

            await client.StartAsync(options);// 异步连接到服务器
        }
    }
}
